// Motion_Indicator.v - Motion Indicator & Display
//
// Description:
// ------------
// Takes an encoded direction input and displays the robot characteristics 
// on the d3 seven segment display.
// 
// Adding FSM Mealy with Synchronous reset 
// State 1:Stop - Segment g on steady
// State 2:Turn Right 1X Speed - Chase clockwise 5 Hz
// State 3:Turn Right 2X Speed - Chase clockwise 10 Hz
// State 4:Turn Left 1X Speed - Chase counterclockwise 5 Hz
// State 5:Turn Left 2X Speed - Chase counterclockwise 10 Hz
// State 6:Forward - Segment a blinks at about 1 Hz
// State 7:Reverse - Segment d blinks at 1 Hz
//
// Input(s) :
// clk, motion_input
// Output(s):
// Hex-to-7Segment
//
// Copyright Jabeer Ahmed and Caleb Mathisen, 2014
// 
// Created By:      Caleb Mathisen
// Author(s) :      Jabeer Ahmed, Caleb Mathisen
// Last Modified:   1/18/2014
//
// Revision History:
// -----------------
///////////////////////////////////////////////////////////////////////////

`timescale  1 ns / 1 ns
module Motion_Indicator(
    //inputs
    input               clk,                // clock    
    input [7:0]         motion_input,    // motion indicator input (0-6) Hex 

    //outputs
    output reg [7:0]    d3 = 8'b11111111 // forces blank digit 
);

// Rotation FSM CW or CCW
reg CW = 1'b1;
reg reset = 1'b0;
reg clock;                      // 5 Hz or 10 Hz
reg [2:0] state;

// Select one based on the input 

// 1 Hz (Forward or Reverse)
// 5 Hz (CW or CCW Slow)
// 10 Hz (CW or CCW Fast)

    localparam seg_a  = 8'b11111110;
    localparam seg_b  = 8'b11111101;
    localparam seg_c  = 8'b11111011;
    localparam seg_d  = 8'b11110111;
    localparam seg_e  = 8'b11101111;
    localparam seg_f  = 8'b11011111;
    localparam seg_g  = 8'b10111111;
    localparam seg_db = 8'b01111111;
    
    localparam dp        = 4'h0;
    localparam Stop      = 4'h1;
    localparam Right_1X  = 4'h2;
    localparam Right_2X  = 4'h3;
    localparam Left_1X   = 4'h4;
    localparam Left_2X   = 4'h5;
    localparam Forward   = 4'h6;
    localparam Reverse   = 4'h7;

    // localparam dp = 1; // decimal point is always off

always @(posedge clock)
    begin
        case (motion_input)
            Stop      : d3 = {dp, seg_g};
            Right_1X  : 
                begin
                    CW = 1;
                    reg    [31:0]   slow_clk_ivl  = 31'd20_000_000;   // 5 Hz
                    reg             set_clock     = 1'b1;
                    RotationFSM // CW
                end
            Right_2X  : 
                begin
                    CW = 1;
                    reg    [31:0]   slow_clk_ivl  = 31'd10_000_000;   // 10 Hz
                    reg             set_clock     = 1'b1;
                    RotationFSM // CW
                end
            Left_1X   : 
                begin
                    CW = 0;
                    reg    [31:0]   slow_clk_ivl  = 31'd20_000_000;   // 5 Hz
                    reg             set_clock     = 1'b1;
                    RotationFSM // CCW
                end   
            Left_2X   : 
                begin
                    CW = 0;
                    reg    [31:0]   slow_clk_ivl  = 31'd10_000_000;   // 10 Hz
                    reg             set_clock     = 1'b1;
                    RotationFSM // CCW
                end   
            Forward   : d3 = {dp, seg_a};
            Reverse   : d3 = {dp, seg_d};
        endcase
    end


// CW = Clockwise, ~CW = Counter Clockwise
function RotationFSM;
   if (reset) state <= 1;
      else case(state)
   1: if (CW) state <= 2;        // Segment a
      else state <= 6;
   2: if (CW) state <= 3;        // Segment b
      else state <= 1;
   3: if (CW) state <= 4;        // Segment c
      else state <= 2;
   4: if (CW) state <= 5;        // Segment d
      else state <= 3;
   5: if (CW) state <= 6;        // Segment e
      else state <= 4;
   6: if (CW) state <= 1;        // Segment f
      else state <= 5;
   default: state <= 1;
endfunction     


endmodule
